package commRedisService

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
)

type RedisManager struct {
	redisMode    RedisModeManager
	redisService RedisServiceManager
}

type RedisServiceManager struct {
	producer map[string]*RedisService  // 生产者
	consumer map[string]*RedisService  // 消费者
	reader   map[string]*RedisOperator // 操作者
	writer   map[string]*RedisOperator // 操作者
}

type RedisModeManager struct {
	producer map[string]interface{} // 生产者模式
	consumer map[string]interface{} // 消费者模式
	reader   map[string]interface{} // 消费者模式
	writer   map[string]interface{} // 消费者模式
}

func (e *RedisManager) GetRedisConsumer() map[string]interface{} {
	return e.redisMode.consumer
}

func (e *RedisManager) GetRedisProducer() map[string]interface{} {
	return e.redisMode.producer
}

func (e *RedisManager) GetRedisReader() map[string]interface{} {
	return e.redisMode.reader
}

func (e *RedisManager) GetRedisWriter() map[string]interface{} {
	return e.redisMode.writer
}

func (e *RedisManager) GetOperatorReader(entityType string) *RedisOperator {
	// 检查：是否为生产者
	_, ok := e.redisMode.reader[entityType]
	if ok {
		p := e.redisService.reader[entityType]
		if p == nil {
			p = e.newRedisOperator(entityType)
			e.redisService.reader[entityType] = p
		}

		return p
	}

	return nil
}

func (e *RedisManager) GetOperatorWriter(entityType string) *RedisOperator {
	// 检查：是否为生产者
	_, ok := e.redisMode.writer[entityType]
	if ok {
		p := e.redisService.writer[entityType]
		if p == nil {
			p = e.newRedisOperator(entityType)
			e.redisService.writer[entityType] = p
		}

		return p
	}

	return nil
}

func (e *RedisManager) GetProducerService(entityType string) *RedisService {
	// 检查：是否为生产者
	_, ok := e.redisMode.producer[entityType]
	if ok {
		p := e.redisService.producer[entityType]
		if p == nil {
			p = e.newRedisService(entityType)
			e.redisService.producer[entityType] = p
		}

		return p
	}

	return nil
}

func (e *RedisManager) GetConsumerService(entityType string) *RedisService {
	// 检查：是否为生产者
	_, ok := e.redisMode.consumer[entityType]
	if ok {
		p := e.redisService.consumer[entityType]
		if p == nil {
			p = e.newRedisService(entityType)
			e.redisService.consumer[entityType] = p
		}

		return p
	}

	return nil
}

func (e *RedisManager) GetRedisService(entityType string) *RedisService {
	// 检查：是否为生产者
	_, ok := e.redisMode.producer[entityType]
	if ok {
		p := e.redisService.producer[entityType]
		if p == nil {
			p = e.newRedisService(entityType)
			e.redisService.producer[entityType] = p
		}

		return p
	}
	// 检查：是否为消费者
	_, ok = e.redisMode.consumer[entityType]
	if ok {
		p := e.redisService.consumer[entityType]
		if p == nil {
			p = e.newRedisService(entityType)
			e.redisService.consumer[entityType] = p
		}

		return p
	}

	return nil
}

func (e *RedisManager) newRedisService(entityType string) *RedisService {
	_, err := commEntity.NewEntity(entityType)
	if err != nil {
		panic("实例化Entity失败:" + entityType)
	}

	redisService := RedisService{}
	redisService.EntityType = entityType
	redisService.agileMap = make(map[string]int64)
	redisService.dataMap = make(map[string]commEntity.IEntity)

	return &redisService
}

func (e *RedisManager) newRedisOperator(entityType string) *RedisOperator {
	_, err := commEntity.NewEntity(entityType)
	if err != nil {
		panic("实例化Entity失败:" + entityType)
	}

	redisOperator := RedisOperator{}
	redisOperator.EntityType = entityType

	return &redisOperator
}

func (e *RedisManager) InitLoadConsumerEntity(entityType string) bool {
	_, ok := e.redisMode.consumer[entityType]
	if ok {
		redisService := e.GetRedisService(entityType)
		if !redisService.IsInited() {
			redisService.reloadRedisService()
		}

		return redisService.IsInited()
	}

	return false
}

func (e *RedisManager) InitLoadProducerEntity(entityType string) bool {
	_, ok := e.redisMode.producer[entityType]
	if ok {
		redisService := e.GetRedisService(entityType)
		if !redisService.IsInited() {
			redisService.reloadRedisService()
		}

		return redisService.IsInited()
	}

	return false
}

func (e *RedisManager) LoadAllEntities(entityType string) error {
	redisService := e.GetRedisService(entityType)
	return redisService.loadAllEntities()
}

func (e *RedisManager) LoadAgileEntities(entityType string) error {
	redisService := e.GetRedisService(entityType)
	return redisService.loadAgileEntities()
}

func (e *RedisManager) SaveAgileEntities(entityType string) error {
	redisService := e.GetProducerService(entityType)
	return redisService.saveAgileEntities()
}

func (e *RedisManager) SaveAllEntities(entityType string) error {
	redisService := e.GetProducerService(entityType)
	return redisService.saveAllEntities()
}

func (e *RedisManager) GetUpdateTime(entityType string) int64 {
	redisService := e.GetRedisService(entityType)
	return redisService.getUpdateTime()
}

func (e *RedisManager) GetEntityById(entityType string, id int64) commEntity.IEntity {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.getEntityById(id)
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.readEntityById(id)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.readEntityById(id)
	}

	redisService := e.GetRedisService(entityType)
	return redisService.getEntityById(id)
}

func (e *RedisManager) GetEntityByServiceKey(entityType string, serviceKey string) (commEntity.IEntity, error) {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.getEntityByKey(serviceKey), nil
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.readEntity(serviceKey)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.readEntity(serviceKey)
	}

	return nil, errors.New("未注册的实体类型：" + entityType)
}

func (e *RedisManager) GetEntityByServiceKeys(entityType string, serviceKeys []string) (map[string]commEntity.IEntity, error) {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.getEntityByKeys(serviceKeys), nil
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.readEntityMap(serviceKeys)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.readEntityMap(serviceKeys)
	}

	return nil, errors.New("未注册的实体类型：" + entityType)
}

func (e *RedisManager) WriteEntity(entity commEntity.IEntity) error {
	redisService := e.GetOperatorWriter(entity.Type())
	return redisService.writeEntity(entity)
}

func (e *RedisManager) UpdateEntity(entity commEntity.IEntity) error {
	if redisService := e.GetProducerService(entity.Type()); redisService != nil {
		return redisService.UpdateEntity(entity)
	}
	if redisService := e.GetOperatorWriter(entity.Type()); redisService != nil {
		return redisService.writeEntity(entity)
	}

	return errors.New("未注册的实体类型：" + entity.Type())
}

func (e *RedisManager) DeleteEntity(entityType string, key string) error {
	if redisService := e.GetProducerService(entityType); redisService != nil {
		redisService.DeleteEntity(key)
		return nil
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.DeleteEntity(key)
	}

	return errors.New("未注册的实体类型：" + entityType)
}

func (e *RedisManager) InsertEntity(entity commEntity.IEntity) {
	if redisService := e.GetProducerService(entity.Type()); redisService != nil {
		redisService.PutEntity(entity)
		return
	}
	if redisService := e.GetOperatorWriter(entity.Type()); redisService != nil {
		redisService.writeEntity(entity)
		return
	}
}

func (e *RedisManager) ForeachEntityList(entityType string, finder func(entity commEntity.IEntity) bool) {
	redisService := e.GetRedisService(entityType)
	redisService.foreachEntityList(finder)
}

func (e *RedisManager) FindEntityList(entityType string, finder func(entity commEntity.IEntity) bool) []commEntity.IEntity {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.findEntityList(finder)
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.findEntityList(finder)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.findEntityList(finder)
	}

	return nil
}

func (e *RedisManager) FindEntity(entityType string, finder func(entity commEntity.IEntity) bool) commEntity.IEntity {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.findEntity(finder)
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.findEntity(finder)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.findEntity(finder)
	}

	return nil
}

func (e *RedisManager) GetEntityCount(entityType string, finder func(entity commEntity.IEntity) bool) (int, error) {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.getEntityCount(finder), nil
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.getEntityCount(finder)
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.getEntityCount(finder)
	}

	return 0, errors.New("未注册的实体类型：" + entityType)
}

// GetEntityMap 复制一个全量数据的副本
func (e *RedisManager) GetEntityMap(entityType string) (map[string]commEntity.IEntity, error) {
	if redisService := e.GetRedisService(entityType); redisService != nil {
		return redisService.copyEntityMap()
	}
	if redisService := e.GetOperatorReader(entityType); redisService != nil {
		return redisService.ReadAllDataMap()
	}
	if redisService := e.GetOperatorWriter(entityType); redisService != nil {
		return redisService.ReadAllDataMap()
	}

	return nil, errors.New("未注册的实体类型：" + entityType)
}

func (e *RedisManager) CopyEntityList(entityType string) []commEntity.IEntity {
	redisService := e.GetRedisService(entityType)
	return redisService.copyEntityList()
}

func (e *RedisManager) BindTypeNotify(entityType string, notify ConsumerTypeNotify) {
	redisService := e.GetConsumerService(entityType)
	redisService.typeNotify = notify
}

func (e *RedisManager) ReloadRedisService(entityType string) bool {
	redisService := e.GetRedisService(entityType)
	return redisService.reloadRedisService()
}

func (e *RedisManager) UpdateRedisService(entityType string) bool {
	redisService := e.GetRedisService(entityType)
	return redisService.updateRedisService()
}

func (e *RedisManager) ReadEntityByServiceKey(entityType string, serviceKey string) (commEntity.IEntity, error) {
	redisService := e.GetOperatorReader(entityType)
	return redisService.readEntity(serviceKey)
}
